import React, { useEffect, useState, memo, useContext } from 'react';
import { connect } from 'umi';
import { history } from 'umi'
import { Form, Button, Spin, Select, message, Row, Icon, Skeleton } from 'antd';
import classNames from 'classnames';

import { BottomAction } from '@/components';
import { withRoutePage } from '@/utils/enhanceUtils';
import AuthComponent from '@/utils/auth/AuthComponent';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import { isSuccess } from '@/utils/request';
import { TabMenuRouter, TabContextMenuFilter } from '@/pages/SalaryManage/components/MenuFilterRouter';
import { TabStoreContext } from '@/pages/SalaryManage/constant/TabStoreContext';

import {
    querySpecialSettingInfo,
    onSaveSpecialSetting,
    queryDictList,
    attendType
} from '@/services/salaryManage/salaryCalculate';
import { NumberSettingInput } from '@/pages/SalaryManage/components/NumberSettingInput';
import EmptyOfSingapore from '@/pages/SalaryManage/components/EmptyOfSingapore';
import ValidateFormTable from '@/pages/SalaryManage/utils/validateFormTable';
import { fetchOrganizationListAndDefault } from '@/pages/SalaryManage/utils';
import OrganizationSelect from '@/components/OrganizationSelect';
import salaryStyle from '@/pages/SalaryManage/salaryManage.less';
import styles from '../style.less';

/** 【特殊设置】权限码 */
const SALARY_SPECIAL_AUTH_CODE = 'finance:setting:salary:special';

const MENU_AUTH_CODE_MAP = {
    CN: [SALARY_SPECIAL_AUTH_CODE],
    SG: [SALARY_SPECIAL_AUTH_CODE]
};

const rulesMap = {
    attendItemCode: [
        {
            required: true,
            msg: '请选择'
        },
        {
            repeat: true,
            msg: '类型重复，请修改'
        }
    ],
    compareType: [
        {
            required: true,
            msg: '请选择'
        }
    ],
    hours: [
        {
            required: true,
            msg: '请填写'
        },
        {
            type: 'number',
            min: 0,
            msg: '小时数不能小于0'
        }
    ],
    ratio: [
        {
            required: true,
            msg: '请填写'
        },
        {
            type: 'number',
            min: 0,
            msg: '百分比不能小于0'
        }
    ]
};

const customFormTable = new ValidateFormTable(rulesMap);

const generateData = () => ({
    attendItemCode: undefined,
    compareType: undefined,
    hours: undefined,
    ratio: undefined,
    id: `special_${new Date().getTime()}_${Math.floor(Math.random() * 100000)}`,
    rules: customFormTable.initRulesFn()
});

const { Option } = Select;
const SpecialForm = memo(({ setPageLoading, selectOrganizationCode }) => {
    const [compareTypeList, setCompareTypeList] = useState([]);
    const [attendList, setAttendList] = useState([]);
    const [dataSource, setDataSource] = useState([]);

    const onSave = async () => {
        customFormTable.validateMessageFn(dataSource, async (err, data) => {
            if (err) {
                setDataSource(data);
                message.error('表单填写有误，请重新调整后提交！');
                return;
            }

            const configData = dataSource.map(({ attendItemCode, compareType, hours, ratio }) => ({
                attendItemCode,
                compareType,
                hours,
                ratio
            }));

            setPageLoading(true);
            try {
                const { code, msg } = await onSaveSpecialSetting({
                    organizationCode: selectOrganizationCode,
                    paramMap: {
                        salarySpecialSubConfig: JSON.stringify(configData)
                    }
                });
                if (code === 10000) {
                    message.success('保存成功！');
                } else {
                    message.error(msg);
                }
                setPageLoading(false);
            } catch (error) {
                console.log(error);
                setPageLoading(false);
            }
        });
    };

    useEffect(() => {
        if (selectOrganizationCode) {
            setPageLoading(true);
            const initFn = async () => {
                const [compareResponse, attendResponse, dataResponse] = await Promise.all([
                    queryDictList('compareTypeEnum'),
                    attendType(selectOrganizationCode),
                    querySpecialSettingInfo(selectOrganizationCode)
                ]);

                if (isSuccess(compareResponse)) {
                    setCompareTypeList(compareResponse.data?.compareTypeEnum || []);
                } else {
                    message.error(compareResponse.msg);
                }
                if (isSuccess(attendResponse)) {
                    setAttendList(attendResponse.data || []);
                } else {
                    message.error(attendResponse.msg);
                }

                if (isSuccess(dataResponse)) {
                    setDataSource(
                        dataResponse.data.salarySpecialSubConfig
                            ? JSON.parse(dataResponse.data.salarySpecialSubConfig).map(item => ({
                                  ...generateData(),
                                  ...item
                              }))
                            : [generateData()]
                    );
                } else {
                    message.error(dataResponse.msg);
                }
            };
            initFn().finally(() => {
                setPageLoading(false);
            });
        }
    }, [selectOrganizationCode, setPageLoading]);

    const addList = () => {
        setDataSource([...dataSource, generateData()]);
    };
    const delList = index => {
        const list = dataSource;
        list.splice(index, 1);
        setDataSource([...list]);
    };

    const handleFn = (index, key, value) => {
        const handleObj = dataSource[index];
        handleObj[key] = value;
        const ruleMsg = customFormTable.ruleValidateMsg(key, value);
        handleObj.rules[key] = ruleMsg;

        setDataSource([...dataSource.slice(0, index), handleObj, ...dataSource.slice(index + 1)]);
    };

    const formItems = dataSource.map((item, index) => (
        <Row key={`${item.id}`} className={styles.flex}>
            <span style={{ lineHeight: '40px', marginRight: 10 }}>同一个月</span>
            <Form.Item
                validateStatus={dataSource[index].rules?.attendItemCode?.validateStatus}
                help={dataSource[index].rules?.attendItemCode?.help}
            >
                <Select
                    style={{ width: 200, marginRight: 10 }}
                    value={dataSource[index].attendItemCode}
                    onChange={v => handleFn(index, 'attendItemCode', v)}
                    placeholder="请选择假种类型"
                >
                    {attendList.map(it => (
                        <Option value={it.attendItemCode} key={it.attendItemCode}>
                            {it.attendItemName}
                        </Option>
                    ))}
                </Select>
            </Form.Item>
            <Form.Item
                validateStatus={dataSource[index].rules?.compareType?.validateStatus}
                help={dataSource[index].rules?.compareType?.help}
            >
                <Select
                    style={{ width: 100, marginRight: 10 }}
                    value={dataSource[index].compareType}
                    onChange={v => handleFn(index, 'compareType', v)}
                    placeholder="请选择"
                >
                    {compareTypeList.map(it => (
                        <Option value={it.key} key={it.key}>
                            {it.value}
                        </Option>
                    ))}
                </Select>
            </Form.Item>
            <Form.Item
                validateStatus={dataSource[index].rules?.hours?.validateStatus}
                help={dataSource[index].rules?.hours?.help}
            >
                <NumberSettingInput
                    value={dataSource[index].hours}
                    onChange={v => handleFn(index, 'hours', v)}
                    style={{ width: 100, marginRight: 10 }}
                />
                小时，按&nbsp;&nbsp;
            </Form.Item>
            <Form.Item
                validateStatus={dataSource[index].rules?.ratio?.validateStatus}
                help={dataSource[index].rules?.ratio?.help}
            >
                <NumberSettingInput
                    value={dataSource[index].ratio}
                    onChange={v => handleFn(index, 'ratio', v)}
                    style={{ width: 100, marginRight: 10 }}
                    suffix="%"
                />
                计算
            </Form.Item>
            {dataSource.length !== 1 ? (
                <Form.Item>
                    <Icon className={styles.specialIcon} onClick={() => delList(index)} type="minus-circle" />
                </Form.Item>
            ) : null}
            {index + 1 === dataSource.length && index + 1 < attendList.length ? (
                <Form.Item>
                    <Icon className={styles.specialIcon} onClick={() => addList()} type="plus-circle" />
                </Form.Item>
            ) : null}
        </Row>
    ));

    return (
        <Form>
            {formItems}
            <AuthComponent code="finance:setting:salary:special:save">
                <BottomAction>
                    <Button type="primary" onClick={onSave}>
                        保存
                    </Button>
                </BottomAction>
            </AuthComponent>
        </Form>
    );
});

const RemindSetting = ({ form }) => {
    const [pageLoading, setPageLoading] = useState(false);
    const [orgLoading, setOrgLoading] = useState(false);
    const [organizationTreeData, setOrganizationTreeData] = useState([]);
    const [selectOrganizationCode, setSelectOrganizationCode] = useState(null);

    const {
        store: { selectOrganizationCode: selOrgCode },
        mergeTabStore
    } = useContext(TabStoreContext);

    useEffect(() => {
        if (selOrgCode && selOrgCode !== selectOrganizationCode) {
            setSelectOrganizationCode(selOrgCode);
        }
    }, [selOrgCode]);

    useEffect(() => {
        setOrgLoading(true);
        fetchOrganizationListAndDefault()
            .then(({ organizationResponse, defaultOrganizationCode: defaultSelectCode }) => {
                setOrganizationTreeData(organizationResponse);
                setSelectOrganizationCode(defaultSelectCode);
            })
            .finally(() => setOrgLoading(false));
    }, []);

    useEffect(() => {
        if (selectOrganizationCode) {
            mergeTabStore({
                selectOrganizationCode,
                countryNameCode: null
            });
        }
    }, [selectOrganizationCode]);

    return (
        <PageHeaderWrapper type="success">
            <TabContextMenuFilter>
                <TabMenuRouter
                    authCodeMap={MENU_AUTH_CODE_MAP}
                    type="specialSetting"
                    extraButton={
                        <div className={salaryStyle.flex}>
                            <div
                                className={classNames([salaryStyle.flex, salaryStyle.mr12])}
                                style={{ fontWeight: 400, lineHeight: '40px' }}
                            >
                                <OrganizationSelect
                                    isStrictly
                                    isNeedPermission
                                    style={{ width: 220 }}
                                    treeDataFromProp
                                    treeDataList={organizationTreeData}
                                    allowClear={false}
                                    dropdownMatchSelectWidth
                                    value={selectOrganizationCode}
                                    onChange={orgCode => setSelectOrganizationCode(orgCode)}
                                />
                            </div>
                            <div>
                                <Button
                                    onClick={() =>
                                        history.push({
                                            pathname: '/finance/setting/salarySetting/specialSettingLog',
                                            state: {
                                                tabRoute: true,
                                                tabRefresh: true
                                            },
                                            query: {
                                                organizationCode: selectOrganizationCode
                                            }
                                        })
                                    }
                                >
                                    操作日志
                                </Button>
                            </div>
                        </div>
                    }
                >
                    <Skeleton loading={orgLoading} active>
                        <EmptyOfSingapore organizationCode={selectOrganizationCode}>
                            <div className={salaryStyle.salaryWrapper}>
                                <Row gutter={24}>
                                    <div className={styles.specialTitle}>薪资特殊扣款配置</div>
                                </Row>

                                <Spin spinning={pageLoading}>
                                    <div
                                        className={styles.container}
                                        style={{ paddingTop: 30, height: 350, paddingLeft: 80 }}
                                    >
                                        <SpecialForm
                                            form={form}
                                            setPageLoading={setPageLoading}
                                            selectOrganizationCode={selectOrganizationCode}
                                        />
                                    </div>
                                </Spin>
                            </div>
                        </EmptyOfSingapore>
                    </Skeleton>
                </TabMenuRouter>
            </TabContextMenuFilter>
        </PageHeaderWrapper>
    );
};
export default withRoutePage(connect(() => ({}))(Form.create({ name: 'specialSetting' })(RemindSetting)));
